package artibella.loaders 
{
	import artibella.IDisposable;
	
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	
	/**
	 * ...
	 * @author pbordachar
	 */
		
	public class LoaderMedia extends Sprite implements IDisposable
	{

		private var _file		:String;
		private var _centered	:Boolean = false;
		private var _smoothed	:Boolean = false;
		private var _checked	:Boolean = false;
		private var _domain		:ApplicationDomain;
		private var _function	:Function;
		private var _agent		:ILoaderAgent;
		
		private var _loader		:Loader;

		
		public function LoaderMedia ( file:String, parameters:LoaderMediaParameters = null, autostart:Boolean = true ){
											   
			_file = file;

			if( parameters != null ){
				_centered = parameters.centered;
				_smoothed = parameters.smoothed;
				_checked = parameters.pfChecked;
				_domain = parameters.domained;
				_function = parameters.onComplete;
				_agent = parameters.agent;
			}
	
			if( _smoothed )	_checked = true ;
			
			if( autostart ){
				addEventListener( Event.ADDED_TO_STAGE, _init );
				addEventListener( Event.REMOVED_FROM_STAGE, _destroy );
			}
		}

		private function _init( e:Event ):void
		{
			load();
		}
		
		public function load():void
		{
			_loader = new Loader();
			
			_addLoaderListeners();
					
			var loaderContext:LoaderContext = new LoaderContext();
			loaderContext.checkPolicyFile = _checked;
			if( _domain != null ) loaderContext.applicationDomain = _domain;
			
			var request:URLRequest = new URLRequest( _file );	
			_loader.load( request, loaderContext );
			
			addChild( _loader );
		}
		
		///////  E C O U T E U R S
		
		private function _addLoaderListeners( ):void
		{
			with ( _loader.contentLoaderInfo ) 
			{
				addEventListener( HTTPStatusEvent.HTTP_STATUS, 			_onHTTPStatus );
				addEventListener( IOErrorEvent.IO_ERROR, 				_onError );
				addEventListener( SecurityErrorEvent.SECURITY_ERROR, 	_onError );
				addEventListener( Event.OPEN, 							_onLoadOpened );
				addEventListener( ProgressEvent.PROGRESS, 				_onLoadProgress );
				addEventListener( Event.INIT, 							_onLoadFinished );
				addEventListener( Event.COMPLETE, 						_onLoadComplete );
			}
			
		}
		
		private function _removeLoaderListeners( ):void
		{
			if (  _loader != null 
			   && _loader.contentLoaderInfo != null 
			   && _loader.contentLoaderInfo.hasEventListener( Event.COMPLETE ) ) {
				   
				with ( _loader.contentLoaderInfo ) 
				{
					removeEventListener( HTTPStatusEvent.HTTP_STATUS, 		_onHTTPStatus );
					removeEventListener( IOErrorEvent.IO_ERROR, 			_onError );
					removeEventListener( SecurityErrorEvent.SECURITY_ERROR, _onError );
					removeEventListener( Event.OPEN, 						_onLoadOpened );
					removeEventListener( ProgressEvent.PROGRESS, 			_onLoadProgress );
					removeEventListener( Event.INIT, 						_onLoadFinished );
					removeEventListener( Event.COMPLETE, 					_onLoadComplete );
				}
			}
		}
		
		///////  C H A R G E M E N T
		
		private function _onHTTPStatus( e:HTTPStatusEvent ):void { }
		
		private function _onError( e:Event ):void
		{
			trace( e );
			trace( _file );
			trace( " " );
			
			_removeLoaderListeners();
			_removeIndicator();
		}
		
		private function _onLoadOpened( e:Event ):void 
		{
			_addIndicator();
		}
		
		private function _onLoadProgress( e:ProgressEvent ):void 
		{
			var percent:int = ( e.bytesLoaded / e.bytesTotal ) * 100;
			_updateIndicator( percent );
		}
		
		private function _onLoadFinished( e:Event ):void 
		{
			_removeIndicator();
		}
		
		private function _onLoadComplete( e:Event ):void 
		{
			_removeLoaderListeners();

			if ( e.target.content is Bitmap ) 
			{
				 e.target.content.smoothing = _smoothed;
			} 

			if ( _centered ) 
			{
				_loader.contentLoaderInfo.loader.x = - _loader.contentLoaderInfo.loader.width / 2;
				_loader.contentLoaderInfo.loader.y = - _loader.contentLoaderInfo.loader.height / 2;
			}
			
			if ( _function != null ) 
			{
				 _function();
				 _function = null;
			}
			
			dispatchEvent( e ); // alternate/additional way
		}
		
		///////  S U I V I   D E   C H A R G E M E N T

		private function _addIndicator():void 
		{
			if ( _agent != null ) 
			{
				 _agent.addIndicator();
			}
		}
		
		private function _removeIndicator():void 
		{
			if ( _agent != null ) 
			{
				 _agent.removeIndicator();
			}
		}
		
		private function _updateIndicator( percent:int ):void 
		{
			if ( _agent != null ) 
			{
				 _agent.updateIndicator( percent );
			}
		}
		
		/////// U T I L I T A I R E S
		
		public function get loader():Loader
		{
			return _loader;
		}
		
		public function get content():*
		{
			return _loader.content;
		}
		
		///////  D E S T R U C T I O N

		private function _destroy( e:Event ):void 
		{
			if ( e != null )
			{
				removeEventListener( Event.ADDED_TO_STAGE, _init );
				removeEventListener( Event.REMOVED_FROM_STAGE, _destroy );
			}
			
			_removeLoaderListeners();

			_function = null;
			_agent = null;
			
			_loader = null;
		}
		
		public function dispose():void 
		{
			_destroy( null );
		}
	}
}